/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * All rights reserved.
 * ****************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************/

/**
*\*\file log.c
*\*\author Nations
*\*\version v1.0.0
*\*\copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
**/
#include "bsp.h"

#if LOG_ENABLE

#include <stdio.h>
#include <file.h>
#include <stdint.h>
#include <stdbool.h>
#include "driverlib.h"

//
// Defines
//

//
// Globals
//
uint16_t deviceOpen = 0;

//
// Functions
//

//
// SCI_open -
//
int SCI_open(const char * path, unsigned flags, int llv_fd)
{
    if(deviceOpen)
    {
        return (-1);
    }
    else
    {
        deviceOpen = 1;
        return (1);
    }
}

//
// SCI_close -
//
int SCI_close(int dev_fd)
{
    if((dev_fd != 1) || (!deviceOpen))
    {
        return (-1);
    }
    else
    {
        deviceOpen = 0;
        return (0);
    }
}

//
// SCI_read -
//
int SCI_read(int dev_fd, char * buf, unsigned count)
{
//    uint16_t readCount = 0;
//    uint16_t * bufPtr = (uint16_t *) buf;
//
//    if(count == 0)
//    {
//        return (0);
//    }
//
//    while((readCount < count) && SCI_isDataAvailableNonFIFO(SCIA_BASE))
//    {
//        *bufPtr = SCI_readCharNonBlocking(SCIA_BASE);
//        readCount++;
//        bufPtr++;
//    }
//
////    while((readCount < count) && SciaRegs.SCIRXST.bit.RXRDY)
////    {
////        *bufPtr = SciaRegs.SCIRXBUF.all;
////        readCount++;
////        bufPtr++;
////    }

    return (0);
}

//
// SCI_write -
//
int SCI_write(int dev_fd, const char * buf, unsigned count)
{
    uint16_t writeCount = 0;
    uint16_t * bufPtr = (uint16_t *) buf;

    if(count == 0)
    {
        return (0);
    }

    while(writeCount < count)
    {
        LIN_writeSCICharBlocking(LINA_BASE, *bufPtr);
        writeCount++;
        bufPtr++;
    }

    return (writeCount);
}

//
// SCI_lseek -
//
off_t SCI_lseek(int dev_fd, off_t offset, int origin)
{
    return (0);
}

//
// SCI_unlink -
//
int SCI_unlink(const char * path)
{
    return (0);
}

//
// SCI_rename -
//
int SCI_rename(const char * old_name, const char * new_name)
{
    return (0);
}


//
// scia_init - SCIA  8-bit word, baud rate 0x001A, default, 1 STOP bit,
// no parity
//
void log_init()
{
    // 配置IO46口为SCIA_TX
    GPIO_setPinConfig(GPIO_46_LINA_TX);
    GPIO_setDirectionMode(46, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(46, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(46, GPIO_QUAL_ASYNC);

    LIN_initModule(LINA_BASE);
    //
    // Enter LIN reset state to perform configurations
    //
    LIN_enterSoftwareReset(LINA_BASE);

    //
    // Switch LIN into SCI mode
    //
    LIN_enableSCIMode(LINA_BASE);

    //
    // Set the SCI communication mode to idle line
    //
    LIN_setSCICommMode(LINA_BASE, LIN_COMM_SCI_IDLELINE);

    //
    // Set SCI to transmit one stop bit
    //
    LIN_setSCIStopBits(LINA_BASE,LIN_SCI_STOP_ONE);

    //
    // Disable parity check
    //
    LIN_disableSCIParity(LINA_BASE);

    //
    // Disable multi-buffer mode
    //
    LIN_disableMultibufferMode(LINA_BASE);

    //
    // Module set to complete operations when halted by debugger
    //
    LIN_setDebugSuspendMode(LINA_BASE, LIN_DEBUG_COMPLETE);

    //
    // Set character length as 8-bits
    //
    LIN_setSCICharLength(LINA_BASE, 8);

    //
    // Set to 1 character in response field
    //
    LIN_setSCIFrameLength(LINA_BASE, 1);

    LIN_setBaudRatePrescaler(LINA_BASE, 53, 4); // 115200
    //
    // Enable Internal Loopback mode
    //
    LIN_disableIntLoopback(LINA_BASE);

    LIN_enableModule(LINA_BASE);

//    //
//    // Enable interrupt for when a frame has been completely received
//    //
//    LIN_enableSCIInterrupt(LINA_BASE, LIN_SCI_INT_RX);
//
//    //
//    // Set the interrupt priority to line 0 (high)
//    //
//    LIN_setSCIInterruptLevel0(LINA_BASE, LIN_SCI_INT_RX);

    //
    // Exit LIN reset state
    //
    LIN_exitSoftwareReset(LINA_BASE);

    // 重定向printf模块使用到的初始化，读写等函数
    add_device("scia", _SSA, SCI_open, SCI_close, SCI_read, SCI_write,
               SCI_lseek, SCI_unlink, SCI_rename);
    fopen("scia","w");
    freopen("scia:", "w", stdout);
    setvbuf(stdout, NULL, _IONBF, 0);

    return;
}

//int fputc(int ch, FILE *f)
//{
//
//     //串口发送函数
//     SCI_writeCharBlockingNonFIFO(SCIA_BASE, ch);
//
//     return ch;
//
// }
//
// End of File
//

#endif /* LOG_ENABLE */
